package cn.lucky.springcloud.service;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author lingpeng.jiang
 * @create 2020-12-28-22:26
 */
@Service
@DefaultProperties(defaultFallback = "globalHystrixTimeoutHandle")
public class HystrixPaymentService {


    /**
     * 正常访问
     * @param id
     * @return
     */
    public String hystrixPaymentInfo_OK(Integer id){
        return "线程池: " + Thread.currentThread().getName() + " hystrixPaymentInfo_OK,id: " + id + "O(∩_∩)O哈哈~";
    }

    /**
     * 超时访问
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "hystrixPaymentInfo_TimeoutHandle",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
    })
    public String hystrixPaymentInfo_Timeout(Integer id){
        int timeout = 3;
        int t = 10/0;
        try {
            TimeUnit.SECONDS.sleep(timeout);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
        return "线程池: " + Thread.currentThread().getName() + " hystrixPaymentInfo_Timeout,端口：8001,id: " + id + "O(∩_∩)O哈哈~";
    }


    /**
     * 单独降级兜底方法
     * @param id
     * @return
     */
    public String hystrixPaymentInfo_TimeoutHandle(Integer id){
        return "线程池: " + Thread.currentThread().getName() + " hystrixPaymentInfo_TimeoutHandle,提供者8001,报错了";
    }

    /**
     * 全局降级兜底方法
     * @return
     */
    public String globalHystrixTimeoutHandle(){
        return "线程池: " + Thread.currentThread().getName() + " 全局降级兜底方法处理,O(∩_∩)O哈哈~";
    }



    /**===========================服务熔断*/

    /**
     *  在10秒的窗口期中至少请求了10次或者在请求的10次中有6次及以上的失败情况下会触发熔断
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "circuitBreakerHandle",commandProperties = {
            //是否启用断路器
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            //设置在滚动时间窗中，断路器熔断的最小请求数。例如，设置该值为10(默认20)的时候
            //如果滚动时间窗设定的时间内没有达到9个请求，即使这9个请求都失败了，断路器也不会打开
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
            //设置当断路器打开之后的休眠时间窗。休眠时间窗结束之后，会将断路器设置为“半开”状态，
            //尝试熔断的请求命令，如果依然失败就将断路器继续设置为 “打开” 状态，如果成功就将断路器设置为“关闭”状态。
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
            //错误百分比阈值（以整数表示，例如默认50），此时断路器将跳闸断开并拒绝请求。
            //在circuitBreaker.sleepWindowInMilliseconds中定义的持续时间内，它将保持跳闸状态
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
    })
    public String circuitBreaker(Integer id){
        if (id < 0){
            throw new RuntimeException("id不能小于零");
        }
        UUID uuid = UUID.randomUUID();
        return "正常返回，流水号为: " + uuid;
    }

    /**
     * 熔断之后的降级方法
     * @param id
     * @return
     */
    public String circuitBreakerHandle(Integer id){
        return "熔断返回";
    }


}
